package com.lifeverse.controller;

import com.lifeverse.common.ApiResponse;
import com.lifeverse.entity.Rule;
import com.lifeverse.entity.enums.RulePriority;
import com.lifeverse.service.RuleEngine;
import com.lifeverse.service.RuleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 规则控制器
 * 提供规则管理的REST API
 */
@Slf4j
@RestController
@RequestMapping("/api/rules")
@RequiredArgsConstructor
public class RuleController {
    
    private final RuleService ruleService;
    private final RuleEngine ruleEngine;
    
    /**
     * 创建规则
     */
    @PostMapping
    public ApiResponse<Rule> createRule(@RequestBody CreateRuleRequest request) {
        try {
            Rule rule = ruleEngine.createRule(
                    request.getName(),
                    request.getDescription(),
                    request.getCategory(),
                    request.getPriority(),
                    request.getConditions(),
                    request.getActions()
            );
            
            return ApiResponse.success(rule);
        } catch (Exception e) {
            log.error("创建规则失败", e);
            return ApiResponse.error("创建规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取规则详情
     */
    @GetMapping("/{ruleId}")
    public ApiResponse<Rule> getRule(@PathVariable Long ruleId) {
        try {
            Rule rule = ruleService.getRule(ruleId);
            return ApiResponse.success(rule);
        } catch (Exception e) {
            log.error("获取规则详情失败 - ID: {}", ruleId, e);
            return ApiResponse.error("获取规则详情失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取所有规则
     */
    @GetMapping
    public ApiResponse<Page<Rule>> getAllRules(@PageableDefault(size = 20) Pageable pageable) {
        try {
            Page<Rule> rules = ruleService.getAllRules(pageable);
            return ApiResponse.success(rules);
        } catch (Exception e) {
            log.error("获取规则列表失败", e);
            return ApiResponse.error("获取规则列表失败: " + e.getMessage());
        }
    }
    
    /**
     * 根据分类获取规则
     */
    @GetMapping("/category/{category}")
    public ApiResponse<List<Rule>> getRulesByCategory(@PathVariable String category) {
        try {
            List<Rule> rules = ruleService.getRulesByCategory(category);
            return ApiResponse.success(rules);
        } catch (Exception e) {
            log.error("获取分类规则失败 - 分类: {}", category, e);
            return ApiResponse.error("获取分类规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 根据优先级获取规则
     */
    @GetMapping("/priority/{priority}")
    public ApiResponse<List<Rule>> getRulesByPriority(@PathVariable RulePriority priority) {
        try {
            List<Rule> rules = ruleService.getRulesByPriority(priority);
            return ApiResponse.success(rules);
        } catch (Exception e) {
            log.error("获取优先级规则失败 - 优先级: {}", priority, e);
            return ApiResponse.error("获取优先级规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取启用的规则
     */
    @GetMapping("/enabled")
    public ApiResponse<List<Rule>> getEnabledRules() {
        try {
            List<Rule> rules = ruleService.getEnabledRules();
            return ApiResponse.success(rules);
        } catch (Exception e) {
            log.error("获取启用规则失败", e);
            return ApiResponse.error("获取启用规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取有效规则
     */
    @GetMapping("/valid")
    public ApiResponse<List<Rule>> getValidRules() {
        try {
            List<Rule> rules = ruleService.getValidRules();
            return ApiResponse.success(rules);
        } catch (Exception e) {
            log.error("获取有效规则失败", e);
            return ApiResponse.error("获取有效规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新规则
     */
    @PutMapping("/{ruleId}")
    public ApiResponse<Rule> updateRule(@PathVariable Long ruleId, @RequestBody UpdateRuleRequest request) {
        try {
            Rule rule = ruleEngine.updateRule(ruleId, request.getConditions(), 
                                            request.getActions(), request.getDescription());
            return ApiResponse.success(rule);
        } catch (Exception e) {
            log.error("更新规则失败 - ID: {}", ruleId, e);
            return ApiResponse.error("更新规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 启用/禁用规则
     */
    @PostMapping("/{ruleId}/toggle")
    public ApiResponse<Rule> toggleRule(@PathVariable Long ruleId, @RequestBody ToggleRuleRequest request) {
        try {
            Rule rule = ruleEngine.toggleRule(ruleId, request.getEnabled());
            return ApiResponse.success(rule);
        } catch (Exception e) {
            log.error("切换规则状态失败 - ID: {}", ruleId, e);
            return ApiResponse.error("切换规则状态失败: " + e.getMessage());
        }
    }
    
    /**
     * 删除规则
     */
    @DeleteMapping("/{ruleId}")
    public ApiResponse<String> deleteRule(@PathVariable Long ruleId) {
        try {
            ruleService.deleteRule(ruleId);
            return ApiResponse.success("规则删除成功");
        } catch (Exception e) {
            log.error("删除规则失败 - ID: {}", ruleId, e);
            return ApiResponse.error("删除规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取规则统计信息
     */
    @GetMapping("/statistics")
    public ApiResponse<RuleEngine.RuleStatistics> getRuleStatistics() {
        try {
            RuleEngine.RuleStatistics statistics = ruleEngine.getRuleStatistics();
            return ApiResponse.success(statistics);
        } catch (Exception e) {
            log.error("获取规则统计信息失败", e);
            return ApiResponse.error("获取规则统计信息失败: " + e.getMessage());
        }
    }
    
    /**
     * 清理过期规则
     */
    @PostMapping("/cleanup-expired")
    public ApiResponse<String> cleanupExpiredRules() {
        try {
            int cleanedCount = ruleEngine.cleanupExpiredRules();
            return ApiResponse.success("清理了 " + cleanedCount + " 个过期规则");
        } catch (Exception e) {
            log.error("清理过期规则失败", e);
            return ApiResponse.error("清理过期规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 搜索规则
     */
    @GetMapping("/search")
    public ApiResponse<List<Rule>> searchRules(@RequestParam String keyword) {
        try {
            List<Rule> rules = ruleService.searchRules(keyword);
            return ApiResponse.success(rules);
        } catch (Exception e) {
            log.error("搜索规则失败 - 关键词: {}", keyword, e);
            return ApiResponse.error("搜索规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取高成功率规则
     */
    @GetMapping("/high-success-rate")
    public ApiResponse<List<Rule>> getHighSuccessRateRules(@RequestParam(defaultValue = "0.8") double threshold) {
        try {
            List<Rule> rules = ruleService.getHighSuccessRateRules(threshold);
            return ApiResponse.success(rules);
        } catch (Exception e) {
            log.error("获取高成功率规则失败", e);
            return ApiResponse.error("获取高成功率规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取低成功率规则
     */
    @GetMapping("/low-success-rate")
    public ApiResponse<List<Rule>> getLowSuccessRateRules(
            @RequestParam(defaultValue = "10") long minExecutions,
            @RequestParam(defaultValue = "0.5") double threshold) {
        try {
            List<Rule> rules = ruleService.getLowSuccessRateRules(minExecutions, threshold);
            return ApiResponse.success(rules);
        } catch (Exception e) {
            log.error("获取低成功率规则失败", e);
            return ApiResponse.error("获取低成功率规则失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取长时间未执行的规则
     */
    @GetMapping("/stale")
    public ApiResponse<List<Rule>> getStaleRules(@RequestParam(defaultValue = "30") int daysThreshold) {
        try {
            List<Rule> rules = ruleService.getStaleRules(daysThreshold);
            return ApiResponse.success(rules);
        } catch (Exception e) {
            log.error("获取长时间未执行规则失败", e);
            return ApiResponse.error("获取长时间未执行规则失败: " + e.getMessage());
        }
    }
    
    // 请求DTO类
    public static class CreateRuleRequest {
        private String name;
        private String description;
        private String category;
        private RulePriority priority;
        private String conditions;
        private String actions;
        
        // getters and setters
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        public String getCategory() { return category; }
        public void setCategory(String category) { this.category = category; }
        public RulePriority getPriority() { return priority; }
        public void setPriority(RulePriority priority) { this.priority = priority; }
        public String getConditions() { return conditions; }
        public void setConditions(String conditions) { this.conditions = conditions; }
        public String getActions() { return actions; }
        public void setActions(String actions) { this.actions = actions; }
    }
    
    public static class UpdateRuleRequest {
        private String conditions;
        private String actions;
        private String description;
        
        // getters and setters
        public String getConditions() { return conditions; }
        public void setConditions(String conditions) { this.conditions = conditions; }
        public String getActions() { return actions; }
        public void setActions(String actions) { this.actions = actions; }
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
    }
    
    public static class ToggleRuleRequest {
        private Boolean enabled;
        
        // getters and setters
        public Boolean getEnabled() { return enabled; }
        public void setEnabled(Boolean enabled) { this.enabled = enabled; }
    }
}